package cn.yueranzs.response;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.yueranzs.config.JwtConfig;
import cn.yueranzs.handler.BusinessException;
import cn.yueranzs.login.common.UserUtil;
import cn.yueranzs.utils.JwtUtil;
import cn.yueranzs.utils.RedisUtil;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 针对返回响应的封装
 * @author yueranzs
 * @date 2021/11/22 14:13
 */
@Data
@Component
public class HttpResponseResult {

    private static JwtConfig jwtConfig;


    @Autowired
    private void setJwtConfig(JwtConfig jwtConfig){
        HttpResponseResult.jwtConfig = jwtConfig;
    }

    /**
     * 基础返回
     * @param resp
     * @param jsonObject
     * @throws IOException
     */
    public static void base(HttpServletResponse resp,JSONObject jsonObject) throws IOException {
        resp.setContentType("application/json;charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.println(jsonObject);
        out.flush();
        out.close();
    }
    /**
     * 响应返回封装
     * @param resp
     * @param resultCode
     * @return
     */
    public static void data(HttpServletResponse resp,CustomizeResultCode resultCode) throws IOException {
        JSONObject result = new JSONObject();
        result.set("code",resultCode.getCode());
        result.set("message",resultCode.getMessage());
        base(resp,result);
    }
    /**
     * 暂无凭证或是认证失败
     * @param resp
     */
    public static void noProof(HttpServletResponse resp) throws IOException {
        data(resp,UserResultCode.USER_NOT_PROOF);
    }
    /**
     * 登录失败
     * @param resp
     * @param exception security的认证异常
     */
    public static void loginError(HttpServletResponse resp,AuthenticationException exception) throws IOException {
        if (exception instanceof LockedException) {
            //账户锁定
            data(resp,UserResultCode.USER_ACCOUNT_LOCKED);
        } else if (exception instanceof CredentialsExpiredException) {
            //密码过期
            data(resp,UserResultCode.USER_CREDENTIALS_EXPIRED);
        } else if (exception instanceof AccountExpiredException) {
            //账户过期
            data(resp,UserResultCode.USER_ACCOUNT_EXPIRED);
        } else if (exception instanceof DisabledException) {
            //账户禁用
            data(resp,UserResultCode.USER_ACCOUNT_DISABLE);
        } else if (exception instanceof BadCredentialsException) {
            //用户名或者密码输入错误
            data(resp,UserResultCode.USER_LOGIN_ERROR_NO);
        }else if (exception instanceof InternalAuthenticationServiceException){
            //用户不存在
            data(resp,UserResultCode.USER_ACCOUNT_NOT_EXIST);
        }
    }

    /**
     * 登录成功
     * @param req
     * @param resp
     * @param auth
     */
    public static void loginSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication auth) throws IOException {
        //生成token
        JwtUtil jwtUtil = new JwtUtil();
        Map<String, Object> user = new HashMap<>();
        user.put("username",auth.getName());
        String token = jwtUtil.create(user);

        //将token存入redis
        RedisUtil.set(RedisResultCode.REDIS_TOKEN_CODE.getMessage() + auth.getName(), token, jwtConfig.getTokenValidityInSeconds(), TimeUnit.SECONDS);

        JSONObject object = new JSONObject();
        object.set("token",token);
        base(resp,new JSONObject().set("code",200).set("data",object));
    }

    /**
     * 权限不足
     * @param req
     * @param resp
     * @param e
     */
    public static void insufficientPermissions(HttpServletRequest req, HttpServletResponse resp, AccessDeniedException e) throws IOException {
        data(resp,UserResultCode.USER_INSUFFICIENT_PERMISSIONS);
    }
}
